package com.m3839.sdk.ym.widget.toast.draggable

import android.graphics.Rect
import android.view.Gravity
import android.view.View
import android.view.View.OnTouchListener
import android.view.WindowManager
import com.m3839.sdk.ym.widget.toast.YMFloatView

/**
 * author : Android 轮子哥
 * github : https://github.com/getActivity/XToast
 * time   : 2019/01/04
 * desc   : 拖拽抽象类
 */
abstract class BaseDraggable : OnTouchListener {
    protected var floatView: YMFloatView? = null
        private set
    protected var rootView: View? = null
        private set
    protected var windowManager: WindowManager? = null
        private set
    protected var windowParams: WindowManager.LayoutParams? = null
        private set

    /**
     * Toast 显示后回调这个类
     */
    fun start(toast: YMFloatView) {
        floatView = toast
        rootView = toast.rootView
        windowManager = toast.windowManager
        windowParams = toast.windowParams
        rootView!!.setOnTouchListener(this)
    }

    /**
     * 获取窗口不可见的宽度，一般情况下为横屏状态下刘海的高度
     */
    protected val windowInvisibleWidth: Int
        protected get() {
            val rect = Rect()
            rootView!!.getWindowVisibleDisplayFrame(rect)
            return rect.left
        }

    /**
     * 获取窗口不可见的高度，一般情况下为状态栏的高度
     */
    protected val windowInvisibleHeight: Int
        protected get() {
            val rect = Rect()
            rootView!!.getWindowVisibleDisplayFrame(rect)
            return rect.top
        }

    /**
     * 更新悬浮窗的位置
     *
     * @param x             x 坐标
     * @param y             y 坐标
     */
    protected fun updateLocation(x: Float, y: Float) {
        updateLocation(x.toInt(), y.toInt())
    }

    /**
     * 更新 WindowManager 所在的位置
     */
    protected fun updateLocation(x: Int, y: Int) {
        // 屏幕默认的重心
        val screenGravity = Gravity.TOP or Gravity.START
        // 判断本次移动的位置是否跟当前的窗口位置是否一致
        if (windowParams!!.gravity == screenGravity && windowParams!!.x == x && windowParams!!.y == y) {
            return
        }
        windowParams!!.x = x
        windowParams!!.y = y
        // 一定要先设置重心位置为左上角
        windowParams!!.gravity = screenGravity
        try {
            windowManager!!.updateViewLayout(rootView, windowParams)
        } catch (ignored: IllegalArgumentException) {
            // 当 WindowManager 已经消失时调用会发生崩溃
            // IllegalArgumentException: View not attached to window manager
        }
    }

    /**
     * 判断用户是否移动了，判断标准以下：
     * 根据手指按下和抬起时的坐标进行判断，不能根据有没有 move 事件来判断
     * 因为在有些机型上面，就算用户没有手指没有移动也会产生 move 事件
     *
     * @param downX         手指按下时的 x 坐标
     * @param upX           手指抬起时的 x 坐标
     * @param downY         手指按下时的 y 坐标
     * @param upY           手指抬起时的 y 坐标
     */
    protected fun isTouchMove(
        downX: Float,
        upX: Float,
        downY: Float,
        upY: Float
    ): Boolean {
        return downX.toInt() != upX.toInt() || downY.toInt() != upY.toInt()
    }
}